'''清洗报表名称字段，去除报表名称中地区、市名以及一些年度季度等干扰项'''

import pandas as pd
import re
import jieba
import jieba.posseg as pseg
import uuid
import warnings

warnings.filterwarnings('ignore')


class ReportNameCleaner:
    def __init__(self):
        # 定义不参与清洗的词汇列表（白名单）
        self.whitelist_words = [
            '社区', '街镇', '镇园区', '园区', '街（镇）', '乡镇', 'XX街道', '行管区', '镇街道', '乡镇街道', '小区',
            '片区', '街道级', '村级', '市政', '市场', '行动区', '地区'
            # 可以根据需要继续添加更多白名单词汇
        ]
        print("报表名称清洗器初始化完成!")

    def preprocess_text(self, text):
        """文本预处理"""
        if pd.isna(text):
            return ""
        text = str(text).strip()
        text = re.sub(r'\s+', ' ', text)
        return text

    def clean_report_name(self, text):
        """清洗报表名称，去除地址和时间信息，但保留白名单词汇"""
        if pd.isna(text) or not text:
            return ""

        text = str(text).strip()

        # 定义要去除的模式
        patterns_to_remove = [
            # 地址相关
            r'[^，。、；：（）()\d\s]+(?:市|区|县|镇|街道|街道级)',
            r'安徽省|包河区|合肥市|宣州区|砀山县|庐阳区|蜀山区|瑶海区|长丰县|肥东县|肥西县|巢湖市|庐江县',
            r'淮北市|亳州市|宿州市|蚌埠市|阜阳市|淮南市|滁州市|六安市|马鞍山市|芜湖市|宣城市|铜陵市|池州市|安庆市|黄山市',
            r'埇桥区|周寨|望东|宁国市|芜湖路|以来|镇西村|望江东路|沈福村|沱河街道',

            # 时间相关
            r'\d{4}年度|\d{2}年度',
            r'\d{4}年|\d{2}年',
            r'2023|2024|2025',
            r'\d{4}月份|\d{1,2}月份',
            r'\d{4}月|\d{1,2}月',
            r'\d{4}-\d{1,2}-\d{1,2}|\d{4}/\d{1,2}/\d{1,2}',
            r'第.季度|第.期',
            r'[一二三四1-4]季度'
        ]

        # 应用所有模式
        cleaned_text = text
        for pattern in patterns_to_remove:
            cleaned_text = re.sub(pattern, '', cleaned_text)

        # 去除多余空格和标点
        cleaned_text = re.sub(r'\s+', ' ', cleaned_text)
        cleaned_text = re.sub(r'^[，。、；：]|[，。、；：]$', '', cleaned_text)
        cleaned_text = cleaned_text.strip()

        # 如果清洗后为空，返回原始文本
        if not cleaned_text:
            return text

        return cleaned_text

    def clean_report_name_advanced(self, text):
        """高级清洗报表名称，使用更智能的方法保留重要词汇"""
        if pd.isna(text) or not text:
            return ""

        text = str(text).strip()

        # 先标记白名单词汇，防止被误删
        protected_text = text
        placeholder_map = {}

        # 为每个白名单词汇创建唯一占位符
        for i, word in enumerate(self.whitelist_words):
            if word in protected_text:
                placeholder = f"PROTECTED_{uuid.uuid4().hex[:8]}_PLACEHOLDER"
                placeholder_map[placeholder] = word
                protected_text = protected_text.replace(word, placeholder)

        # 定义要去除的模式
        patterns_to_remove = [
            # 地址相关
            r'[^，。、；：（）()\d\s]+(?:市|区|县|镇|街道|街道级)',
            r'安徽省|包河区|合肥市|宣州区|砀山县|庐阳区|蜀山区|瑶海区|长丰县|肥东县|肥西县|巢湖市|庐江县',
            r'淮北市|亳州市|宿州市|蚌埠市|阜阳市|淮南市|滁州市|六安市|马鞍山市|芜湖市|宣城市|铜陵市|池州市|安庆市|黄山市',
            r'埇桥区|周寨|望东|宁国市|芜湖路|以来|镇西村|望江东路|沈福村',

            # 时间相关
            r'\d{4}年度|\d{2}年度',
            r'\d{4}年|\d{2}年',
            r'2023|2024|2025',
            r'\d{4}月份|\d{1,2}月份',
            r'\d{4}月|\d{1,2}月',
            r'\d{4}-\d{1,2}-\d{1,2}|\d{4}/\d{1,2}/\d{1,2}',
            r'第.季度|第.期',
            r'[一二三四1-4]季度',
            r'补充录入-|（）'
        ]

        # 应用所有模式到受保护的文本
        cleaned_text = protected_text
        for pattern in patterns_to_remove:
            # 确保占位符不会被误删
            temp_cleaned = re.sub(pattern, '', cleaned_text)

            # 检查是否有占位符被误删
            for placeholder in placeholder_map.keys():
                if placeholder in cleaned_text and placeholder not in temp_cleaned:
                    # 如果占位符被误删，恢复原始文本
                    temp_cleaned = cleaned_text
                    break

            cleaned_text = temp_cleaned

        # 恢复白名单词汇
        for placeholder, original_word in placeholder_map.items():
            cleaned_text = cleaned_text.replace(placeholder, original_word)

        # 去除多余空格和标点
        cleaned_text = re.sub(r'\s+', ' ', cleaned_text)
        cleaned_text = re.sub(r'^[，。、；：]|[，。、；：]$', '', cleaned_text)
        cleaned_text = cleaned_text.strip()

        # 如果清洗后为空，返回原始文本
        if not cleaned_text:
            return text

        return cleaned_text


def clean_excel_report_names(input_file, sheet_name, report_name_column='报表名称',
                             output_sheet_name='清洗后数据', use_advanced_cleaning=True):
    """
    清洗Excel文件中指定sheet的报表名称字段

    参数:
    input_file: Excel文件路径
    sheet_name: 要处理的sheet名称
    report_name_column: 报表名称字段的列名
    output_sheet_name: 输出sheet的名称
    use_advanced_cleaning: 是否使用高级清洗方法
    """

    # 初始化清洗器
    cleaner = ReportNameCleaner()

    # 读取Excel文件
    print(f"正在读取Excel文件: {input_file}")
    try:
        df = pd.read_excel(input_file, sheet_name=sheet_name)
        print(f"成功读取数据，共 {len(df)} 行")
    except Exception as e:
        print(f"读取文件失败: {e}")
        return None

    # 检查报表名称列是否存在
    if report_name_column not in df.columns:
        print(f"错误: 数据中不存在 '{report_name_column}' 列")
        print(f"可用列名: {list(df.columns)}")
        return None

    # 复制原始数据，不修改源数据
    result_df = df.copy()

    # 清洗报表名称
    print("正在清洗报表名称...")
    if use_advanced_cleaning:
        result_df['清洗后报表名称'] = result_df[report_name_column].apply(
            lambda x: cleaner.clean_report_name_advanced(x)
        )
        print("使用高级清洗方法")
    else:
        result_df['清洗后报表名称'] = result_df[report_name_column].apply(
            lambda x: cleaner.clean_report_name(x)
        )
        print("使用基础清洗方法")

    # 将结果写入新的sheet
    print(f"正在将结果写入新的sheet: {output_sheet_name}")
    try:
        with pd.ExcelWriter(input_file, engine='openpyxl', mode='a', if_sheet_exists='replace') as writer:
            result_df.to_excel(writer, sheet_name=output_sheet_name, index=False)
        print("清洗完成! 结果已保存到新的sheet中")
    except Exception as e:
        print(f"保存结果失败: {e}")
        # 如果追加模式失败，尝试新建文件
        try:
            output_file = input_file.replace('.xlsx', '_清洗后.xlsx')
            with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
                result_df.to_excel(writer, sheet_name=output_sheet_name, index=False)
            print(f"清洗完成! 结果已保存到新文件: {output_file}")
        except Exception as e2:
            print(f"保存到新文件也失败: {e2}")
            return None

    # 打印清洗统计信息
    print("\n=== 清洗结果统计 ===")
    print(f"总数据条数: {len(result_df)}")
    print(f"原始报表名称数量: {result_df[report_name_column].nunique()}")
    print(f"清洗后报表名称数量: {result_df['清洗后报表名称'].nunique()}")
    print(f"清洗方法: {'高级清洗' if use_advanced_cleaning else '基础清洗'}")

    return result_df


# 使用示例
if __name__ == "__main__":
    # 配置参数
    input_file = "C:/Users/xingwenzheng/Desktop/用于导入的 历史报表模板-1016.xlsx"  # 替换为你的文件路径
    sheet_name = "处理后的数据"  # 替换为你的sheet名称
    report_name_column = "报表名称"  # 替换为你的报表名称字段名

    # 执行清洗
    result = clean_excel_report_names(
        input_file=input_file,
        sheet_name=sheet_name,
        report_name_column=report_name_column,
        output_sheet_name='清洗后数据',
        use_advanced_cleaning=True
    )